/*
    Down In Front: The Android Application
    This application is an interface for Down In Front commentaries.
    Copyright (C) 2011
    Holden Hill <holdenhill@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package down.in.front;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.apache.http.util.ByteArrayBuffer;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

/**
 * This is the activity that loads up the archive list that appears when the app
 * first starts.
 * 
 * @author Holden Hill <holdenhill@gmail.com>
 * 
 */
public class ArchiveView extends Activity {
	// Create objects for use within this activity.
	private ProgressDialog loadProgress;
	private ListView l1;
	private String update = "";

	// Create static variables to pass data into the release view. In hindsight,
	// I can probably pass these through the intent that starts ReleaseView. For
	// another update!
	static int current;
	static ArrayList<Episode> episodes;

	// Create path for file downloads.
	private final String PATH = "/data/data/down.in.front/";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.archive);

		l1 = (ListView) findViewById(R.id.ArchiveList);
		episodes = new ArrayList<Episode>();

		// Create a progress dialog to display while images are being
		// downloaded.
		loadProgress = ProgressDialog.show(this, "Down In Front",
				"Checking for updates.\n\nPlease wait...", false);

		new Thread(new Runnable() {
			@Override
			public void run() {
				// Variables for reading in from the web server.
				BufferedReader rd;
				String line = "", fulltext = "";

				// Try to download and save the JSON data.
				try {
					URL url = new URL("http://www.downinfront.net/json.php");
					URLConnection ucon = url.openConnection();
					rd = new BufferedReader(new InputStreamReader(ucon
							.getInputStream()));

					while ((line = rd.readLine()) != null)
						fulltext += line;
				} catch (Exception e) {
					Log.e("DOWN IN FRONT : JSON",
							"Could not establish a connection to the JSON file.");
				}

				try {
					JSONArray entries = new JSONArray(fulltext);

					// Update the progress dialog while a file is being
					// downloaded.
					for (int i = 0; i < entries.length(); i++) {
						JSONObject movies = entries.getJSONObject(i);

						// Check for background images.
						if (Drawable.createFromPath(PATH + "app-" + (i + 1)
								+ ".jpg") == null) {
							update = "Downloading updates.\n\nEpisode "
									+ (i + 1) + " of " + entries.length()
									+ "\n" + movies.getString("title");
							updateHandler.sendEmptyMessage(0);
							downloadBackgrounds(movies.getString("imagelink"),
									i + 1);
						}

						// Check for poster images.
						if (Drawable.createFromPath(PATH + "poster-" + (i + 1)
								+ ".jpg") == null) {
							update = "Downloading updates.\n\nEpisode "
									+ (i + 1) + " of " + entries.length()
									+ "\n" + movies.getString("title");
							updateHandler.sendEmptyMessage(0);
							downloadPosters(
									"http://www.downinfront.net/images/posters/poster-"
											+ (i + 1) + ".jpg", i + 1);
						}

						// Fill the array list with an Episode entry for each
						// commentary.
						episodes.add(new Episode(i + 1, movies
								.getString("title"), //
								// Trash any HTML Teague thought he would be
								// clever with.
								movies.getString("commentators").replaceAll(
										"\\<.*?>", //
										""), movies.getString("description")
										.replaceAll("\\<.*?>", ""), //
								movies.getString("tags"),//
								movies.getString("link"), //
								PATH + "app-" + (i + 1) + ".jpg", //
								PATH + "poster-" + (i + 1) + ".jpg"));
					}
				} catch (JSONException e) {
					// TODO This will work for now.
					Log.w("DOWN IN FRONT :JSON", "We threw an error? What?");
					e.printStackTrace();
				}

				uiHandler.sendEmptyMessage(0);
			}
		}).start();
	}

	/**
	 * Connects each list entry to the release view for that episode.
	 */
	private Handler uiHandler = new Handler() {
		@Override
		public void handleMessage(Message message) {
			loadProgress.dismiss();

			ArchiveAdapter adapter = new ArchiveAdapter(getBaseContext(),
					episodes);
			l1.setAdapter(adapter);
			l1.setOnItemClickListener(new OnItemClickListener() {

				@Override
				public void onItemClick(AdapterView<?> arg0, View arg1,
						int arg2, long arg3) {
					// Create a new ReleaseView for this episode.
					current = episodes.size() - arg2 - 1;
					ArchiveView.this.startActivity(new Intent(getBaseContext(),
							ReleaseView.class));
				}
			});
		};
	};

	/**
	 * Updates the progress dialog. Meh.
	 */
	private Handler updateHandler = new Handler() {
		@Override
		public void handleMessage(Message message) {
			loadProgress.setMessage(update);
		}
	};

	/**
	 * Downloads the background images into internal memory.
	 * 
	 * @param from
	 *            The URL containing the path to the image on the web.
	 * @param id
	 *            An Integer containing the id of that particular episode.
	 */
	public void downloadBackgrounds(String from, int id) {
		try {
			URL url = new URL(from);
			File file = new File("app-" + id + ".jpg");
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "download begining");
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "download url:" + url);
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "downloaded file name:"
					+ "app-" + id + ".jpg");

			// Open a connection to that file.
			URLConnection ucon = url.openConnection();
			InputStream is = ucon.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(is);
			ByteArrayBuffer baf = new ByteArrayBuffer(50);
			int current = 0;

			// Write it to storage.
			while ((current = bis.read()) != -1) {
				baf.append((byte) current);
			}

			// Kill everything.
			FileOutputStream fos = new FileOutputStream(PATH + file);
			fos.write(baf.toByteArray());
			fos.close();
		} catch (IOException e) {
			Log.d("DOWN IN FRONT : IMAGE MANAGER", "Error: " + e);
		}
	}

	/**
	 * Downloads the background images into internal memory.
	 * 
	 * @param from
	 *            The URL containing the path to the image on the web.
	 * @param id
	 *            An Integer containing the id of that particular episode.
	 */
	public void downloadPosters(String from, int id) {
		try {
			URL url = new URL(from);
			File file = new File("poster-" + id + ".jpg");
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "download begining");
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "download url:" + url);
			Log.i("DOWN IN FRONT : IMAGE MANAGER", "downloaded file name:"
					+ "poster-" + id + ".jpg");

			// Establish a connection to the image.
			URLConnection ucon = url.openConnection();
			InputStream is = ucon.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(is);
			ByteArrayBuffer baf = new ByteArrayBuffer(50);
			int current = 0;

			// Write it.
			while ((current = bis.read()) != -1) {
				baf.append((byte) current);
			}

			// Kill it.
			FileOutputStream fos = new FileOutputStream(PATH + file);
			fos.write(baf.toByteArray());
			fos.close();
		} catch (IOException e) {
			Log.d("DOWN IN FRONT : IMAGE MANAGER", "Error: " + e);
		}
	}
}
